package cfs.controller;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.mybeans.dao.DAOException;
import org.mybeans.form.FormBeanException;
import org.mybeans.form.FormBeanFactory;

import cfs.databean.CFSTransaction;
import cfs.databean.Customer;
import cfs.databean.Fund;
import cfs.databean.Position;
import cfs.formbean.SellFundEntry;
import cfs.formbean.SellFundFormBean;
import cfs.helper.Helper;
import cfs.helper.TransactionTypes;
import cfs.model.FundDAO;
import cfs.model.Model;
import cfs.model.PositionDAO;
import cfs.model.TransactionDAO;

public class SellFundAction extends Action {

	private FormBeanFactory<SellFundFormBean> formBeanFactory = FormBeanFactory
			.getInstance(SellFundFormBean.class);

	private PositionDAO positionDAO;
	private FundDAO fundDAO;
	private TransactionDAO transactionDAO;

	public SellFundAction(Model model) {
		positionDAO = model.getPositionDao();
		fundDAO = model.getFundDao();
		transactionDAO = model.getTransactionDao();

	}

	@Override
	public String getName() {
		return "sellFund.do";
	}

	@Override
	public String perform(HttpServletRequest request) {

//		HttpSession session = request.getSession();
		List<String> errors = new ArrayList<String>();
		request.setAttribute("errors", errors);

		try {
			SellFundFormBean form = formBeanFactory.create(request);
			Customer user = (Customer) request.getSession()
					.getAttribute("user");

			if (!form.isPresent()) {// first access this page
				initializeFundList(request, errors, user);
				return "SellFund.jsp";
			}

			errors.addAll(form.getValidationErrors());

			if (errors.size() > 0) {
				initializeFundList(request, errors, user);
				return "SellFund.jsp";
			}

			Double sellAmountDouble = Double.parseDouble(form
					.getNumberOfShares());
			long sellAmountInt = Helper.double3ToLong(sellAmountDouble);

			int fund_id = Integer.parseInt(form.getSelectedFund());
			long availableShares = positionDAO.getAvailableShares(
					user.getCustomer_id(), fund_id);

			if (availableShares < sellAmountInt) {
				errors.add("Number of shares must be less than the available shares");
			}

			if (errors.size() > 0) {
				initializeFundList(request, errors, user);
				return "SellFund.jsp";
			}

			CFSTransaction transactionObj = new CFSTransaction();
			transactionObj.setCustomer_id(user.getCustomer_id());
			transactionObj.setRequest_date(new Date((new java.util.Date().getTime())));
			transactionObj.setFund_id(fund_id);
			transactionObj.setShares(sellAmountInt);
			transactionObj.setStatus(Helper.PENDING_STATUS);
			transactionObj.setTransaction_type(TransactionTypes.SELL_FUND);

			// Putting the transaction into transaction table.
			transactionDAO.create(transactionObj);

			long newAvailableShares = availableShares - sellAmountInt;
			// Updating the Available number of shares
			positionDAO.updateAvailableShares(user.getCustomer_id(), fund_id,
					newAvailableShares);

			request.setAttribute("msg",
					"Operation Successful !!");

			initializeFundList(request, errors, user);

		} catch (FormBeanException e1) {
			e1.printStackTrace();
		} catch (DAOException e) {
			e.printStackTrace();
		}
		return "customerTransaction.do";
	}

	private void initializeFundList(HttpServletRequest request,
			List<String> errors, Customer user) throws DAOException {
		Position[] fundList = positionDAO.getFunds(user.getCustomer_id());
		List<SellFundEntry> entryList = new ArrayList<SellFundEntry>();
		if (fundList == null || fundList.length == 0) {
			errors.add("User does not have any shares");
		} else {
			for (int i = 0; i < fundList.length; i++) {
				SellFundEntry entry = new SellFundEntry();
				entry.setAvailableShares(Helper.longToDouble3String(fundList[i]
						.getAvailableshares()));
				Fund obj = fundDAO.getFundMap(fundList[i].getFund_id());
				entry.setFund_id("" + obj.getFund_id());
				entry.setName(obj.getName());
				entry.setSymbol(obj.getSymbol());
				entryList.add(entry);
			}
		}
		request.setAttribute("fundList", entryList);
	}
}
